package com.tticar.invmanager.service.impl;

import com.baomidou.mybatisplus.entity.Column;
import com.baomidou.mybatisplus.entity.Columns;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tticar.invmanager.common.Enum.CodeType;
import com.tticar.invmanager.common.Enum.Status;
import com.tticar.invmanager.common.exception.MyServiceException;
import com.tticar.invmanager.common.shiro.MySecurityUtils;
import com.tticar.invmanager.common.utils.tree.TreeUtils;
import com.tticar.invmanager.entity.MCateogry;
import com.tticar.invmanager.entity.MCateogrySku;
import com.tticar.invmanager.entity.MMateriel;
import com.tticar.invmanager.entity.MMaterielSku;
import com.tticar.invmanager.entity.MSku;
import com.tticar.invmanager.entity.vo.MyPage;
import com.tticar.invmanager.entity.vo.Tree;
import com.tticar.invmanager.mapper.MCateogryMapper;
import com.tticar.invmanager.mapper.MCateogrySkuMapper;
import com.tticar.invmanager.service.ICodeCounterService;
import com.tticar.invmanager.service.IMCateogryService;
import com.tticar.invmanager.service.IMMaterielService;
import com.tticar.invmanager.service.IMSkuService;
import com.tticar.invmanager.tticar.service.IGoodsService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 存货分类表 服务实现类
 * </p>
 *
 * @author joeyYan
 * @since 2018-07-03
 */
@Service
public class MCateogryServiceImpl extends ServiceImpl<MCateogryMapper, MCateogry> implements IMCateogryService {
    @Autowired
    private MCateogrySkuMapper cateogrySkuMapper;
    @Autowired
    private IMSkuService mSkuService;
    @Autowired
    ICodeCounterService codeCounterService;
    @Autowired
    IMMaterielService materielService;
    @Autowired
    private IGoodsService goodsService;

    @Override
    public Page selectPage(MCateogry mCateogry, MyPage<MCateogry> page) {
        Wrapper wrapper = new EntityWrapper();
        Columns columns = Columns.create().column("*");
        columns.column("(select case count(1) when 0 then 'open' else 'closed' end from m_cateogry t where t.pid=m_cateogry.id and t.status <> -1)", "state");
//        columns.column("(case pid when 0 then 'closed' else 'open' end)", "state");
        wrapper.setSqlSelect(columns);
        if (mCateogry.getStatus() == null) {
            wrapper.ne(Status.STATUS.getDesc(), Status.DELETE.getCode());
        } else {
            wrapper.eq(Status.STATUS.getDesc(), mCateogry.getStatus());
        }
        if (Strings.isEmpty(mCateogry.getName())
                && (mCateogry.getId() == null || mCateogry.getId() == 0)) {
            wrapper.eq( MCateogry.PID, 0);
        } else if (mCateogry.getId() != null && mCateogry.getId() != 0) {
            wrapper.eq(MCateogry.PID, mCateogry.getId());
        } else if (Strings.isNotEmpty(mCateogry.getName())){
            wrapper.like(Strings.isNotEmpty(mCateogry.getName()), MCateogry.NAME, mCateogry.getName());
        }
//        else if (Strings.isNotEmpty(mCateogry.getName())) {
//            wrapper.eq( MCateogry.PID, 0);
//        }
//        if (mCateogry.getId() == null || mCateogry.getId() == 0) {
//            wrapper.like(Strings.isNotEmpty(mCateogry.getName()), MCateogry.NAME, mCateogry.getName());
//        }
        wrapper.orderBy("sort", true);
        return this.selectMapsPage(page, wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<Long> ids) {
        List list = new ArrayList();
        for (Long id : ids) {
            Wrapper wrapper = new EntityWrapper<>();
            wrapper.ne("status", -1);
            wrapper.eq("pid", id);
            List<MCateogry> mCateogries = selectList(wrapper);
            if (mCateogries != null && mCateogries.size() > 0) {
                throw new MyServiceException("该分类下有子分类，不可删除");
            }
            Wrapper wrapper1 = new EntityWrapper<>();
            wrapper1.ne("status", "-1");
            wrapper1.eq("category_id", id);
            List<MMateriel> mMateriels = materielService.selectList(wrapper1);
            if (mMateriels != null && mMateriels.size() > 0) {
                throw new MyServiceException("该分类下有存货商品，不可删除");
            }
            checkIsUsed(id, Status.DELETE.getCode());
        }
        // 删除分类
        this.deleteBatchIds(ids);
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.in("pid",ids);
        // 删除分类的子集
        this.delete(wrapper);
    }

    @Override
    public List msku(MCateogrySku cateogrySku) {
        Wrapper<MCateogrySku> w = Condition.create();
        w.setSqlSelect(Column.create().column(MCateogrySku.SKU_ID));
        w.eq(MCateogrySku.CATEGORY_ID, cateogrySku.getCategoryId());
        w.orderBy(MCateogrySku.SORT);
        List<Map<String, Object>> list = cateogrySkuMapper.selectMaps(w);
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            Long skuId = MapUtils.getLong(map, MCateogrySku.SKU_ID);
            MSku sku = mSkuService.selectById(skuId);
            if (sku != null) {
                map.put(MSku.NAME, sku.getName());
            }
            // 只获取状态为0有效的sku
            if (sku != null && sku.getStatus() == 0) {
                resultList.add(map);
            }
        }
        return resultList;
    }

    @Override
    public List<MCateogrySku> getCateogrySkuList(List<Long> cateogryIdList) {
        if (CollectionUtils.isEmpty(cateogryIdList)) {
            return null;
        }
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.in(MCateogrySku.CATEGORY_ID, cateogryIdList);
        return cateogrySkuMapper.selectList(wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSku(List<MCateogrySku> cateogrySku) {
        for (MCateogrySku mcs : cateogrySku) {
            if (mcs.getId() == -1) {
                mcs.setId(null);
                cateogrySkuMapper.delete(new EntityWrapper(mcs));
            } else {
                mcs.setId(null);
                cateogrySkuMapper.insert(mcs);
            }
        }
    }

    @Override
    public List getTree(Long id) {
        if (id == null) id = 0l;
        Wrapper<MCateogry> w = Condition.create().eq(MCateogry.STATUS, MCateogry.ZERO);
        w.eq(MCateogry.PID, id);
        w.orderBy("sort", true);
        Columns columns = Columns.create()
                .column(MCateogry.ID).column(MCateogry.NAME, "text")
                .column("(select case count(1) when 0 then 'open' else 'closed' end from m_cateogry t where t.pid=m_cateogry.id and t.status <> -1)", "state");
        w.setSqlSelect(columns);
        return this.selectMaps(w);
//        return recursion(0l);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(MCateogry mCateogry) {
        if (mCateogry.getId() != null && mCateogry.getStatus() != 0) {
            Wrapper wrapper = new EntityWrapper<>();
            wrapper.ne("status", -1);
            wrapper.eq("pid", mCateogry.getId());
            List<MCateogry> mCateogries = selectList(wrapper);
            if (mCateogries != null && mCateogries.size() > 0) {
                throw new MyServiceException("该分类下有子分类，不可禁用");
            }
            Wrapper wrapper1 = new EntityWrapper<>();
            wrapper1.ne("status", "-1");
            wrapper1.eq("category_id", mCateogry.getId());
            List<MMateriel> mMateriels = materielService.selectList(wrapper1);
            if (mMateriels != null && mMateriels.size() > 0) {
                throw new MyServiceException("该分类下有存货商品，不可禁用");
            }
        }

        if (mCateogry.getId() == null || mCateogry.getId() == 0) {
            String middle = "1";
            mCateogry.setCategoryType(1);
            if (mCateogry.getPid() != null && mCateogry.getPid() != 0) {
                Wrapper wrapper = new EntityWrapper<>();
                wrapper.eq("id", mCateogry.getPid());
                List<MCateogry> mCateogries = selectList(wrapper);
                if (mCateogries != null && mCateogries.size() > 0) {
                    Integer categoryType = mCateogries.get(0).getCategoryType();
                    if (categoryType !=null && categoryType == 1) {
                        middle = "2";
                        mCateogry.setCategoryType(2);
                    } else {
                        middle = "3";
                        mCateogry.setCategoryType(3);
                    }
                }

            }
            mCateogry.setCode(codeCounterService.getCode(CodeType.FL, middle, 4));


        } else {
            checkIsUsed(mCateogry.getId(), mCateogry.getStatus());
        }

        //isLeaf
        if(mCateogry.getId() == null) {
            mCateogry.setIsLeaf(1);

            if(mCateogry.getCategoryType() == 2) {
                MCateogry p = this.selectById(mCateogry.getPid());
                p.setIsLeaf(0);
                this.updateById(p);
            }
            if(mCateogry.getCategoryType() == 3) {
                MCateogry p = this.selectById(mCateogry.getPid());
                p.setIsLeaf(0);
                this.updateById(p);

                MCateogry pp = this.selectById(p.getPid());
                pp.setIsLeaf(0);
                this.updateById(pp);
            }
        }

        this.insertOrUpdate(mCateogry);
    }

    private List recursion(Long pid) {
        Wrapper<MCateogry> w = Condition.create().eq(MCateogry.STATUS, MCateogry.ZERO);
        w.eq(MCateogry.PID, pid);
        Columns columns = Columns.create()
                .column(MCateogry.ID).column(MCateogry.NAME, "text")
                .column("(select case count(1) when 0 then 'open' else 'closed' end from m_cateogry t where t.pid=m_cateogry.id and t.status <> -1)", "state");
        w.setSqlSelect(columns);
        List list = this.selectMaps(w);
        for (Object obj : list) {
            Map map = (Map) obj;
            String state = MapUtils.getString(map, "state");
            if ("closed".equals(state)) {
                map.put("children", recursion(MapUtils.getLong(map, "id")));
            }
        }
        return list;
    }

    private void checkIsUsed(Long id, int status) {
        if (status == Status.DELETE.getCode() || status == Status.INVALID.getCode()) {
            Wrapper wrapper = new EntityWrapper<>();
            wrapper.eq("category_id", id);
            wrapper.ne("status", Status.DELETE.getCode());
            List list = materielService.selectList(wrapper);
            if (CollectionUtils.isNotEmpty(list)) {
                MCateogry cateogry = this.selectById(id);
                String msg = "此数据已被使用，不可禁用或删除";
                msg = "（"+ cateogry.getName() + ")" + msg;
                throw new MyServiceException(msg);
            }
        }
    }

    @Override
    public List<Tree> tree() {
        List<Tree> resultList = new ArrayList<>();
        Tree root = new Tree(0L,"全部");
        resultList.add(root);

        List<MCateogry> list = this.baseMapper.tree(MySecurityUtils.currentUser().getTenantId());

        for(int i=0; i<list.size(); i++) {
            MCateogry cate = list.get(i);
            Tree tree = new Tree(cate.getId(), cate.getName());
            tree.setPid(cate.getPid());
            tree.setState(cate.getIsLeaf() == 1 ? "open" : "closed");
            resultList.add(tree);
        }

        TreeUtils.createTree(resultList, root, "id", "pid", "children");
        List<Tree> treeList = root.getChildren();//知道2级的数据不展示
        List<Tree> rList = new ArrayList<>();
        for(Tree tree : treeList) {
            if(tree.getChildren() != null && tree.getChildren().size() > 0) {
                rList.add(tree);
            }
        }
        return rList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void synchronizationFromTticar() {
        List<Map> category = goodsService.synchronizationCategory();
        List list = new ArrayList<>();
        for (Map map : category) {
            MCateogry mCateogry = new MCateogry();
            String name = (String) map.get("name");

            mCateogry.setName(name);
            mCateogry.setSort((Integer) map.get("sort"));
            mCateogry.setStatus(0);
            mCateogry.setId((Long) map.get("id"));
            mCateogry.setPid((Long) map.get("parentId"));
            //如果父类没插入，那他也不能插入
            Boolean isExist = false;

            if (list.contains(mCateogry.getPid())) {
                list.add(mCateogry.getId());
                isExist = true;
            }

            String groupName = (String) map.get("groupName");
            //不包含>>为1级分类
            if (!groupName.contains(">>")) {
                mCateogry.setCategoryType(1);
                mCateogry.setCode(codeCounterService.getCode(CodeType.FL, "1", 4));
                mCateogry.setPid(0L);
            } else if (groupName.contains(">>")) {
                groupName = groupName.substring(groupName.indexOf(">>") + 2, groupName.length());
                //包含2个>>为3级分类
                Wrapper wrapper = new EntityWrapper<>();
                String pName = null;
                if (groupName.contains(">>")) {
                    mCateogry.setCategoryType(3);
                    pName = groupName.substring(0,groupName.indexOf(">>"));
                    mCateogry.setCode(codeCounterService.getCode(CodeType.FL, "3", 4));
                } else {
                    //包含1个>>为2级分类
                    mCateogry.setCategoryType(2);
                    String newString = (String) map.get("groupName") ;
                    pName = newString.substring(0,newString.indexOf(">>"));
                    mCateogry.setCode(codeCounterService.getCode(CodeType.FL, "2", 4));
                }
                wrapper.eq("name", pName);
                List<MCateogry> mCateogries = selectList(wrapper);
                if (mCateogries != null && mCateogries.size() > 0) {
                    Long id = mCateogries.get(0).getId();
                    mCateogry.setPid(id);
                }

            }

            Wrapper wrapper = new EntityWrapper<>();
            List<MCateogry> mCateogries1 = selectList(wrapper);

            if (mCateogries1 != null && mCateogries1.size() > 0) {
                for (MCateogry mCateogry1 : mCateogries1) {
                    //同名分类就跳过
                    if (mCateogry1.getName().equals(name) ) {
                        list.add(mCateogry.getId());
                        isExist = true;
                    }
                }
            }


            //如果不存在才插入
            if (!isExist) {
                mCateogry.setIsLeaf(1);
                insert(mCateogry);
                //更新父菜单的isleaf 为0
                MCateogry parentCateogry = new MCateogry();
                parentCateogry.setIsLeaf(0);
                parentCateogry.setId(mCateogry.getPid());
                updateById(parentCateogry);
            }
        }
    }

}
